<template>
  <div class="bpmn">
    <div ref="canvas" style="width: 100%; height: 100%"></div>
    <div ref="propertiesPanel" class="panel"></div>
  </div>
</template>
<script setup lang="js">
import translate from '@/components/bpmn/translate'
import BpmnModeler from 'bpmn-js/lib/Modeler';
import { useI18n } from 'vue-i18n';
import MoveCanvasModule from 'diagram-js/lib/navigation/movecanvas'; // 轻量级 move 模块
import ZoomScrollModule from 'diagram-js/lib/navigation/zoomscroll'; // 缩放模块
import {
  BpmnPropertiesPanelModule,
  BpmnPropertiesProviderModule,
  CamundaPlatformPropertiesProviderModule
} from 'bpmn-js-properties-panel';
var customTranslateModule = {
  translate: ['value', translate]
}
import camundaModdle from 'camunda-bpmn-moddle/resources/camunda.json';
import { onMounted, onUpdated, ref } from "vue";

import { processDefinitionApi } from "@/api/workflow";
const { t } = useI18n();
const props = defineProps({
  xmlStr: {
    type: String,
    default: xmlStr
  },
  version: {
    type: Number,
    default: null
  },
  highlightActiveNodes: {
    type: Array,
    default: []
  }
})
const xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
  "<bpmn2:definitions xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:bpmn2=\"http://www.omg.org/spec/BPMN/20100524/MODEL\" xmlns:bpmndi=\"http://www.omg.org/spec/BPMN/20100524/DI\" xmlns:dc=\"http://www.omg.org/spec/DD/20100524/DC\" xmlns:di=\"http://www.omg.org/spec/DD/20100524/DI\" xsi:schemaLocation=\"http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd\" id=\"sample-diagram\" targetNamespace=\"http://bpmn.io/schema/bpmn\">\n" +
  "  <bpmn2:process id=\"Process_1\" isExecutable=\"true\" camunda:historyTimeToLive=\"P0D\" camunda:versionTag=\"1\">\n" +
  "    <bpmn2:startEvent camunda:initiator=\"${applicant}\" id=\"StartEvent_1\"/>\n" +
  "  </bpmn2:process>\n" +
  "  <bpmndi:BPMNDiagram id=\"BPMNDiagram_1\">\n" +
  "    <bpmndi:BPMNPlane id=\"BPMNPlane_1\" bpmnElement=\"Process_1\">\n" +
  "      <bpmndi:BPMNShape id=\"_BPMNShape_StartEvent_2\" bpmnElement=\"StartEvent_1\">\n" +
  "        <dc:Bounds height=\"36.0\" width=\"36.0\" x=\"412.0\" y=\"240.0\"/>\n" +
  "      </bpmndi:BPMNShape>\n" +
  "    </bpmndi:BPMNPlane>\n" +
  "  </bpmndi:BPMNDiagram>\n" +
  "</bpmn2:definitions>";
const propertiesPanel = ref(null);
let viewer;
const canvas = ref()

onUpdated(async () => {
  if (viewer) {
    viewer.destroy();
  }
  viewer = new BpmnModeler({
    container: canvas.value,
    propertiesPanel: {
      parent: propertiesPanel.value,
    },
    additionalModules: [
      BpmnPropertiesPanelModule,
      BpmnPropertiesProviderModule,
      CamundaPlatformPropertiesProviderModule,
      customTranslateModule,
      MoveCanvasModule,
      ZoomScrollModule
    ],
    moddleExtensions: {
      camunda: camundaModdle
    }
  });
  let data = xmlStr
  if (props.xmlStr) {
    data = props.xmlStr
  }
  viewer.importXML(data)
    .then(function (result) {
      addEventBusListener()
      viewer.get('canvas').zoom('fit-viewport');
      if (props.version) {
        viewer.get('canvas').getRootElement().businessObject.versionTag = props.version
      }
      highlightActiveNodes()
    }).catch(function (err) {
      const { warnings, message } = err;
      console.log('something went wrong:', warnings, message);
    });
})

const addEventBusListener = () => {
  const eventBus = viewer.get('eventBus')
  const eventTypes = ['element.changed'] // 需要监听的事件集合
  eventTypes.forEach(function (eventType) {
    eventBus.on(eventType, function (e) {
    })
  })
}

const saveXml = () => {
  return new Promise((resolve) => {
    viewer.saveXML(
      { format: true }
    ).then((xml) => {
      let formData = new FormData()
      formData.append('version', viewer.get('canvas').getRootElement().businessObject.versionTag)
      formData.append('deploymentSource', 'manage')
      formData.append('deploymentName', viewer.get('canvas').getRootElement().businessObject.name)
      formData.append('enableDuplicateFiltering', false)
      formData.append("data", new Blob([xml.xml], { type: 'text/xml' }), viewer.get('canvas').getRootElement().businessObject.name + '.bpmn');
      processDefinitionApi.import(formData).then(res => {
        resolve(true)
      })
    })
  })
}

const highlightActiveNodes = () => {
  const canvas = viewer.get('canvas')
  canvas.getRootElement().children.forEach(element => {
    if (props.highlightActiveNodes.includes(element.id)) {
      canvas.addMarker(element, 'highlight')
    }
  })
}

defineExpose({ saveXml, highlightActiveNodes })

</script>
<style>
@import "bpmn-js/dist/assets/diagram-js.css";
@import "bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css";
@import "bpmn-js/dist/assets/bpmn-font/css/bpmn.css";
@import "bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css";
@import "@bpmn-io/properties-panel/dist/assets/properties-panel.css";

.bpmn {
  height: 100%;
  width: 100%;
  position: relative;
  overflow: auto;
}

.bjs-powered-by {
  display: none !important;
}

.bpp-textfield input {
  padding-right: 0;
}

.panel {
  position: absolute;
  top: 0;
  right: 0;
  height: 100%;
  overflow: auto;
}

/* 任务节点样式 */
.djs-shape.task rect {
  fill: #8fd14f;
  /* 背景色 */
  stroke: #5a8f3b;
  /* 边框颜色 */
  stroke-width: 2px;
  /* 边框宽度 */
}

/* 连接线样式 */
.djs-connection .djs-visual line {
  stroke: #333;
  /* 线条颜色 */
  stroke-width: 2px;
  /* 线条宽度 */
}

/* 高亮样式 */
.highlight:not(.djs-connection) .djs-visual> :nth-child(1) {
  fill: #bdf4c2 !important;
  /* 高亮颜色 */
}

/* 文本标签样式 */
.djs-label {
  font-size: 14px;
  color: #333;
}
</style>